package my.webservices.util;

import java.io.FileOutputStream;
import java.io.OutputStream;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.springframework.core.io.FileSystemResource;
import org.springframework.ws.wsdl.wsdl11.DynamicWsdl11Definition;
import org.springframework.ws.wsdl.wsdl11.builder.XsdBasedSoap11Wsdl4jDefinitionBuilder;

/**
 * WsdlCreator is a utility class for creating wsdl files from xml schema.
 * 
 * @author Nilaksh Bajpai.
 */
public final class WsdlCreator {

  /**
   * Deault constructor.
   */
  private WsdlCreator() {

  }

  /**
   * Used to create a wsdl file from the specified xsd. Uses spring's
   * {@link org.springframework.ws.wsdl.wsdl11.DynamicWsdl11Definition} to
   * create a wsdl source which is finally written to the passed output
   * stream.
   * 
   * This process is done outside the spring context because of what appears
   * to be a bug as a result of conflict in version of wsdl4j jar.The app
   * server seems to use an older than required version. This issue is logged
   * at <a href="http://jira.springframework.org/browse/SWS-166">http://jira.
   * springframework.org/browse/SWS-166</a>.
   * 
   * Although this issue is logged for websphere 6.1 the same appears to be
   * true for wls 8.1. To confirm this a unit test was done, details of which
   * could be found at
   * {@link com.sapient.javapractice.springws.vhs.webservice.test.XsdBasedSoap11Wsdl4jDefinitionBuilderTest}.
   * 
   * 
   * @param xsdPath
   * @param portTypeName
   * @param schemaPrefix
   * @param locationUri
   * @param out
   * @throws Exception
   */
  public static void create(final String xsdPath, final String portTypeName, final String schemaPrefix, final String locationUri,
      final OutputStream out) throws Exception {
    XsdBasedSoap11Wsdl4jDefinitionBuilder builder = new XsdBasedSoap11Wsdl4jDefinitionBuilder();
    builder.setSchema(new FileSystemResource(xsdPath));
    builder.setPortTypeName(portTypeName);
    builder.setSchemaPrefix(schemaPrefix);
    builder.setLocationUri(locationUri);
    builder.afterPropertiesSet();
    DynamicWsdl11Definition definition = new DynamicWsdl11Definition();
    definition.setBuilder(builder);
    definition.afterPropertiesSet();
    Source source = definition.getSource();
    Result result = new StreamResult(out);
    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    transformer.transform(source, result);
  }

  /**
   * Wrapper for {@link #create(String, String, String, String, OutputStream)}
   * .
   * 
   * @param xsdPath
   * @param portTypeName
   * @param schemaPrefix
   * @param locationUri
   * @param wsdlPath
   * @throws Exception
   */
  public static void create(final String xsdPath, final String portTypeName, final String schemaPrefix, final String locationUri,
      final String wsdlPath) throws Exception {
    OutputStream out = new FileOutputStream(wsdlPath);
    create(xsdPath, portTypeName, schemaPrefix, locationUri, out);
  }

  /**
   * Main method for test.
   * 
   * @param args
   * @throws Exception
   */
  public static void main(final String[] args) throws Exception {
    try {
      create("/Users/khushi_neel/code/java/vehicle-search-service-spring/src/test/java/my/webservices/util/input.xsd", "Input",
          "tns", "http://localhost:2233/vehicle-search-service-spring/vehicle-history-search-service",
          "/Users/khushi_neel/code/java/vehicle-search-service-spring/src/test/java/my/webservices/util/"
              + "wsdl/VehicleHistoryService.wsdl");
    } catch (Exception e) {
      throw e;
    }

  }
}
